package com.hardy.Thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Author: fuxh3@lenovo.com
 * Date: Created in 2018/1/12 0012
 */
public class ThreadPoolTest {
    /**
     * 创建一个固定长度的线程池，每当提交一个任务就创建一个线程，直到达到线程池的最大数量，这时线程规模将不再变化，当线程发生未预期的错误而结束事
     * 线程池会补充一个新的线程
     * 阻塞队列用的是LinkedBlockingQueue
     */
    private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
    /**
     * 创建一个可缓存的线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收的线程，则新建线程
     * 阻塞队列用的是SynchronousQueue
     */
    private static ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
    /**
     * 创建一个定长的线程池，支持定时和周期的执行任务,可控制线程最大的并发数
     * 阻塞队列用的是DelayedWorkQueue
     */
    private static ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
    /**
     * 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
     */
    private static ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
    static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        cacheThreadTest();
        fixedThread();
        singleThread();
        scheduledThreadTest();
    }

    private static void cacheThreadTest() {
        try {
            lock.lock();
            for (int i = 0; i < 10; i++) {
                final int index = i;
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                cacheThreadPool.execute(new Runnable() {
                    @Override public void run() {
                        System.out.println("cacheThreadPool-------" + index);
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private static void fixedThread() {
        try {
            lock.lock();
            for (int i = 0; i < 10; i++) {
                final int index = i;
                fixedThreadPool.execute(new Runnable() {
                    @Override public void run() {
                        try {
                            System.out.println("fixedThreadPool-------" + index);
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private static void scheduledThreadTest() {
        try {
            lock.lock();
            for (int i = 0; i < 10; i++) {
                final int index = i;
                scheduledThreadPool.execute(new Runnable() {
                    @Override public void run() {
                        try {
                            System.out.println("scheduledThreadPool-------" + index);
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private static void singleThread() {
        try {
            lock.lock();
            for (int i = 0; i < 10; i++) {
                final int index = i;
                singleThreadPool.execute(new Runnable() {
                    @Override public void run() {
                        try {
                            System.out.println("singleThreadPool-------" + index);
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
